home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / osr5 / sco / scripts / bigcal < prev    next >
Encoding:
Korn shell script  |  1997-08-26  |  15.2 KB  |  705 lines

  1. #!/bin/ksh
  2. # bigcal: print a big calendar
  3. # @(#) bigcal.ksh 2.1 96/11/13
  4. # 90/06 John H. DuBois III (john@armory.com)
  5. # 91/01/13 cleaned up slightly.
  6. # 95/03/23 Print help without pausing.  Added description of f option to help.
  7. #          Changed argument format.
  8. # 95/08/01 Added s option.
  9. # 96/11/13 Added X option.
  10.  
  11. # Prints a calendar with squares, with digits printed in various fonts,
  12. # and optionally filled with data.
  13. # Uses 'cal' to get the digits.
  14. # Use -h to for help.
  15.  
  16. # The output of "cal" is expected to be in a format like this:
  17.  
  18. #   June 1990
  19. # S  M Tu  W Th  F  S
  20. #                1  2
  21. # 3  4  5  6  7  8  9
  22. #10 11 12 13 14 15 16
  23. #17 18 19 20 21 22 23
  24. #24 25 26 27 28 29 30
  25.  
  26. # Set defaults.  The meaning of these vars is described in help.
  27. box=ascii
  28. t=- b=- l=\| r=\| tl=- bl=- tr=- br=- m=+ h=- v=\|    # Set ascii box chars.
  29. hsize=9
  30. vsize=5
  31. digits=1
  32. ReadFields=false
  33. short=false
  34. debug=false
  35.  
  36. lname=${0##*/}
  37. Usage=\
  38. "Usage: $lname [-hfs] [-b<boxtype>] [-d<digits>] [-c<name=value[,...]>]
  39.               [-x<width>] [-y<height>] [<month>]"
  40.  
  41. while getopts :fhb:d:x:y:c:sX opt; do
  42.     case $opt in
  43.     h)
  44.     echo \
  45. "$lname: print a big (box-style) calendar.
  46. $Usage
  47. $lname prints a calendar for month <month>.  <month> should be in the same
  48. format as that recognized by /bin/cal, except that a single numeric argument
  49. for month will be interpreted as a month number rather than a year, and a
  50. year given as two digits is assumed to be in the century 19xx.  If <month>
  51. is not given, a calendar for the current month is printed.
  52. Options:
  53. -h: print this help.
  54. -s: Merge the date header into the first box line.
  55. -f: Read data to be printed in boxes from the standard input.  The first line
  56.     read is printed in the box for the first day of the month, etc.  Each
  57.     word on the line is printed on a separate line in the box.
  58. -b<boxtype>: <boxtype> should be either ascii, ibm1, or ibm2.  The calendar
  59.     boxes are printed using characters from the specified set.  ascii is the
  60.     default and will work on any ascii device.  ibm1 and ibm2 look much better
  61.     but will only work on devices that implement the IBM extended character
  62.     set; for example, a PC console, IBM-compatible graphic printers, and Wyse
  63.     60 terminals.
  64. -d<digits>: <digits> should be one of 1, 5, ibm1_3, ibm1_5, ibm2_3, or ibm2_5.
  65.     Date digits are drawn using the specified font.  1 is the normal
  66.     single-character digits; 5 is a font drawn with ascii characters that is 5
  67.     characters high; ibmn_h is a font drawn using the n-line box drawing
  68.     characters that is h characters high.  The ibmn_h fonts work on devices as
  69.     described for box.
  70. -c<name=value[,...]>: Set the box drawing characters.  This option should not
  71.     be used with -b.  The assignments are done by a comma-separated string of
  72.     name=value pairs.  The names and the box components they set are:
  73.     t, b, l, r: used where a bar joins with the outer top, left, bottom, and
  74.     right bar of the calendar.
  75.     tl, bl, tr, br: used for the top left, bottom left, top right, and bottom
  76.     right corner of the calendar.
  77.     m: middle; used where a horizontal and vertical bar cross each other.
  78.     h, v: used for drawing horizontal and vertical bars.
  79. -x<width>: The interior width of individual date boxes is set to <width>.  The
  80.     default is $hsize.
  81. -y<height>: The interior height of individual date boxes is set to <height>. 
  82.     The default is $vsize."
  83.     exit 0
  84.     ;;
  85.     f)
  86.     ReadFields=true;;
  87.     b)
  88.     box=$OPTARG;;
  89.     d)
  90.     digits=$OPTARG;;
  91.     x)
  92.     hsize=$OPTARG;;
  93.     X)
  94.     debug=true;;
  95.     y)
  96.     vsize=$OPTARG;;
  97.     c)
  98.     boxchars=$OPTARG;;
  99.     s)
  100.     short=true;;
  101.     +?)
  102.     print -u2 "$lname: options should not be preceded by a '+'."
  103.     exit 1
  104.     ;;
  105.     :) 
  106.     print -u2 "$lname: Option '$OPTARG' requires a value.  Use -h for help."
  107.     exit 1
  108.     ;;
  109.     ?) 
  110.     print -u2 "$lname: $OPTARG: bad option.  Use -h for help."
  111.     exit 1
  112.     ;;
  113.     esac
  114. done
  115.  
  116. # remove args that were options
  117. let OPTIND=OPTIND-1
  118. shift $OPTIND
  119.  
  120. case $# in
  121. 0)
  122.     month=`date +%h`    # default month is current month
  123.     ;;
  124. 1)
  125.     month=$1
  126.     # if month is given numerically without a year, add year to it because
  127.     # /bin/date assumes a single numeric argument is a year.
  128.     [[ "$month" = +([0-9]) ]] && month="$month "`date +19%y`
  129.     ;;
  130. 2)
  131.     [[ "$2" = [0-9][0-9] ]] && month="$1 19$2" || month="$*"
  132.     ;;
  133. *)
  134.     print -u2 "$Usage\nUse -h for help."
  135.     exit 1
  136.     ;;
  137. esac
  138.  
  139. if [ -n "$boxchars" ]; then
  140.     OIFS=$IFS
  141.     IFS=,
  142.     set -- $boxchars
  143.     IFS=$OIFS
  144.     for arg; do
  145.     case $arg in
  146.         @([tblrmhv]|[tb][lr])=*) eval ${arg%%=*}=\"${arg#*=}\";;
  147.     esac
  148.     done
  149. fi
  150.  
  151. # set chars for drawing box-style digits.  Names explained in help data.
  152. case $digits in
  153. ibm2_*)
  154.     t="\0313" b="\0312" l="\0314" r="\0271" tl="\0311" bl="\0310"
  155.     tr="\0273" br="\0274" m="\0316" h="\0315" v="\0272"
  156.     ;;
  157. ibm1_*)
  158.     t="\0302" b="\0301" l="\0303" r="\0264" tl="\0332" bl="\0300"
  159.     tr="\0277" br="\0331" m="\0305" h="\0304" v="\0263"
  160.     ;;
  161. esac
  162.  
  163. # Set arrays n0..n9 and nb (blank) to digit fonts.
  164. # Each element of the array is a row of chars for the digit.
  165. # digheight is the number of rows in each digit. 
  166. # gap is the string used to separate two digits.
  167. # digwidth is the width of two digits + gap
  168. case $digits in
  169. 1)
  170.     digheight=1 digwidth=2 gap=
  171.     n0=0 n1=1 n2=2 n3=3 n4=4 n5=5 n6=6 n7=7 n8=8 n9=9 nb=' '
  172.     ;;
  173. 5)
  174.     digheight=5 digwidth=9 gap=' '
  175.     set -A n0 \
  176. ' __ ' \
  177. '/  \' \
  178. '|  |' \
  179. '|  |' \
  180. '\__/'
  181.  
  182.     set -A n1 \
  183. '    ' \
  184. '  | ' \
  185. '  | ' \
  186. '  | ' \
  187. '  | '
  188.  
  189.     set -A n2 \
  190. ' __ ' \
  191. '/  |' \
  192. '  / ' \
  193. ' /  ' \
  194. '/___'
  195.  
  196.     set -A n3 \
  197. ' __ ' \
  198. '/  \' \
  199. '  _/' \
  200. '   \' \
  201. '\__/'
  202.     set -A n4 \
  203. '    ' \
  204. '| | ' \
  205. '|_|_' \
  206. '  | ' \
  207. '  | '
  208.  
  209.     set -A n5 \
  210. '____' \
  211. '|   ' \
  212. '|__ ' \
  213. '   \' \
  214. '\__/'
  215.  
  216.     set -A n6 \
  217. ' __ ' \
  218. '/  `' \
  219. '|__ ' \
  220. '|  \' \
  221. '\__/'
  222.  
  223.     set -A n7 \
  224. '____' \
  225. '   /' \
  226. '  / ' \
  227. ' /  ' \
  228. '/   '
  229.  
  230.     set -A n8 \
  231. ' __ ' \
  232. '/  \' \
  233. '\__/' \
  234. '/  \' \
  235. '\__/'
  236.  
  237.     set -A n9 \
  238. ' __ ' \
  239. '/  \' \
  240. '\__|' \
  241. '   |' \
  242. '\__/'
  243.  
  244.     set -A nb \
  245. '    ' \
  246. '    ' \
  247. '    ' \
  248. '    ' \
  249. '    '
  250.     ;;
  251. ibm1_3|ibm2_3)
  252.     digheight=3 digwidth=5 gap=' '
  253.     set -A n0 -- \
  254. "$tl$tr" \
  255. "$v$v" \
  256. "$bl$br"
  257.  
  258.     set -A n1 -- \
  259. "$tr " \
  260. "$v " \
  261. "$b "
  262.  
  263.     set -A n2 -- \
  264. " $tr" \
  265. "$tl$br" \
  266. "$bl "
  267.  
  268.     set -A n3 -- \
  269. "$tr " \
  270. "$r " \
  271. "$br "
  272.  
  273.     set -A n4 -- \
  274. "$v$v" \
  275. "$bl$r" \
  276. " $v"
  277.  
  278.     set -A n5 -- \
  279. "$tl " \
  280. "$bl$tr" \
  281. " $br"
  282.  
  283.     set -A n6 -- \
  284. "$tl " \
  285. "$l$tr" \
  286. "$bl$br"
  287.  
  288.     set -A n7 -- \
  289. "$h$tr" \
  290. " $v" \
  291. " $v"
  292.  
  293.     set -A n8 -- \
  294. "$tl$tr" \
  295. "$l$r" \
  296. "$bl$br"
  297.  
  298.     set -A n9 -- \
  299. "$tl$tr" \
  300. "$bl$r" \
  301. " $v"
  302.  
  303.     set -A nb -- \
  304. "  " \
  305. "  " \
  306. "  "
  307.     ;;
  308. ibm1_5|ibm2_5)
  309.     digheight=5 digwidth=7 gap=' '
  310.     set -A n0 -- \
  311. "$tl$h$tr" \
  312. "$v $v" \
  313. "$v $v" \
  314. "$v $v" \
  315. "$bl$h$br"
  316.  
  317.     set -A n1 -- \
  318. " $tr " \
  319. " $v " \
  320. " $v " \
  321. " $v " \
  322. " $b "
  323.  
  324.     set -A n2 -- \
  325. " $h$tr" \
  326. "  $v" \
  327. "$tl$h$br" \
  328. "$v  " \
  329. "$bl$h "
  330.  
  331.     set -A n3 -- \
  332. " $h$tr" \
  333. "  $v" \
  334. " $h$r" \
  335. "  $v" \
  336. " $h$br"
  337.  
  338.     set -A n4 -- \
  339. "$v $v" \
  340. "$v $v" \
  341. "$bl$h$r" \
  342. "  $v" \
  343. "  $v"
  344.  
  345.     set -A n5 -- \
  346. "$tl$h " \
  347. "$v  " \
  348. "$bl$h$tr" \
  349. "  $v" \
  350. " $h$br"
  351.  
  352.     set -A n6 -- \
  353. "$tl$h " \
  354. "$v  " \
  355. "$l$h$tr" \
  356. "$v $v" \
  357. "$bl$h$br"
  358.  
  359.     set -A n7 -- \
  360. "$h$h$tr" \
  361. "  $v" \
  362. "  $v" \
  363. "  $v" \
  364. "  $v"
  365.  
  366.     set -A n8 -- \
  367. "$tl$h$tr" \
  368. "$v $v" \
  369. "$l$h$r" \
  370. "$v $v" \
  371. "$bl$h$br"
  372.  
  373.     set -A n9 -- \
  374. "$tl$h$tr" \
  375. "$v $v" \
  376. "$bl$h$r" \
  377. "  $v" \
  378. "  $v"
  379.  
  380.     set -A nb -- \
  381. "   " \
  382. "   " \
  383. "   " \
  384. "   " \
  385. "   "
  386.     ;;
  387. ibm1_5w|ibm2_5w)
  388.     digheight=5 digwidth=9 gap=' '
  389.     set -A n0 -- \
  390. "$tl$h$h$tr" \
  391. "$v  $v" \
  392. "$v  $v" \
  393. "$v  $v" \
  394. "$bl$h$h$br"
  395.  
  396.     set -A n1 -- \
  397. " $tr  " \
  398. " $v  " \
  399. " $v  " \
  400. " $v  " \
  401. " $b  "
  402.  
  403.     set -A n2 -- \
  404. " $h$h$tr" \
  405. "   $v" \
  406. "$tl$h$h$br" \
  407. "$v   " \
  408. "$bl$h$h "
  409.  
  410.     set -A n3 -- \
  411. " $h$h$tr" \
  412. "   $v" \
  413. " $h$h$r" \
  414. "   $v" \
  415. " $h$h$br"
  416.  
  417.     set -A n4 -- \
  418. "$v  $v" \
  419. "$v  $v" \
  420. "$bl$h$h$r" \
  421. "   $v" \
  422. "   $v"
  423.  
  424.     set -A n5 -- \
  425. "$tl$h$h " \
  426. "$v   " \
  427. "$bl$h$h$tr" \
  428. "   $v" \
  429. " $h$h$br"
  430.  
  431.     set -A n6 -- \
  432. "$tl$h$h " \
  433. "$v   " \
  434. "$l$h$h$tr" \
  435. "$v  $v" \
  436. "$bl$h$h$br"
  437.  
  438.     set -A n7 -- \
  439. "$h$h$h$tr" \
  440. "   $v" \
  441. "   $v" \
  442. "   $v" \
  443. "   $v"
  444.  
  445.     set -A n8 -- \
  446. "$tl$h$h$tr" \
  447. "$v  $v" \
  448. "$l$h$h$r" \
  449. "$v  $v" \
  450. "$bl$h$h$br"
  451.  
  452.     set -A n9 -- \
  453. "$tl$h$h$tr" \
  454. "$v  $v" \
  455. "$bl$h$h$r" \
  456. "   $v" \
  457. "   $v"
  458.  
  459.     set -A nb -- \
  460. "    " \
  461. "    " \
  462. "    " \
  463. "    " \
  464. "    "
  465.     ;;
  466. *)
  467.     echo "$lname: bad value for digits: $digits.  Exiting."
  468.     exit 1
  469.     ;;
  470. esac
  471.  
  472. # Select box drawing characters.
  473. # If default (ascii) selected, chars are defaults set for ascii
  474. # before argument processing, unless modified during arg processing
  475. # by setting of t, b, etc. on command line.
  476. case $box in
  477. ascii)
  478.     ;;
  479. ibm2)
  480.     t="\0313" b="\0312" l="\0314" r="\0271" tl="\0311" bl="\0310"
  481.     tr="\0273" br="\0274" m="\0316" h="\0315" v="\0272"
  482.     ;;
  483. ibm1) 
  484.     t="\0302" b="\0301" l="\0303" r="\0264" tl="\0332" bl="\0300"
  485.     tr="\0277" br="\0331" m="\0305" h="\0304" v="\0263"
  486.     ;;
  487. *)
  488.     echo "$lname: bad box font name $box.  Exiting."
  489.     exit 1
  490.     ;;
  491. esac
  492.  
  493. # printhorbar size leftchar middlechar rightchar horchar
  494. # Print a horizontal bar.
  495. # size is the interior length of each section
  496. # leftchar is the char to start the bar with
  497. # middlechar is the char to join two sections with
  498. # rightchar is the char to end the bar with
  499. # horchar is the char to draw each section with
  500. # 7 sections are drawn.
  501. # Example: the bar /---+---+---+---+---+---+---\ is generated by
  502. # printhorbar 3 / + '\' -
  503. printhorbar() {
  504.     typeset -i i=0
  505.     # generate bar section of specified length
  506.     horbar=
  507.     while [ i -lt $1 ]; do
  508.     horbar=$horbar$5
  509.     let i+=1
  510.     done
  511.     echo -n $2$horbar    # print left char & first section
  512.     i=0
  513.     while [ i -lt 6 ]; do
  514.     echo -n $3$horbar
  515.     let i+=1
  516.     done
  517.     echo $4
  518. }
  519.  
  520. # printver size sepchar datasize [<field1data> [... <field7data>]]
  521. # print a section of a rectangle
  522. # size is the interior (horizontal) length of each section
  523. # sepchar is the char to separate each section with
  524. # datasize is the length each data field will be after escape sequences
  525. # in them are resolved by "echo"
  526. # If it is 0, data are of various lengths, but there are no escape sequences
  527. # so data fields can be forced to a specific length
  528. printver() {
  529.     $debug && print -ru2 -- "printver $*"
  530.     sep=$2
  531.     if [ $3 = 0 ]; then
  532.     # set field var to length size+length(sep)
  533.     typeset -L$(($1 + ${#sep})) field
  534.     else
  535.     # set blank padding to length size-datasize
  536.     typeset -L$(($1 - $3)) blanks
  537.     fi
  538.     # size typeset does not have effect until assignment to var is made
  539.     blanks=
  540.     shift 3
  541.     typeset -i i=0
  542.     while [ i -lt 7 ]; do
  543.     field="$sep$1"
  544.     echo -n "$field$blanks"
  545.     let i+=1
  546.     [ $# -gt 0 ] && shift
  547.     done
  548.     echo $sep
  549. }
  550.  
  551. # if -f given, read data for fields into d[] from stdin
  552. typeset -i i=1
  553. if $ReadFields; then
  554.     while read d[i] && [ i -lt 32 ]; do 
  555.     let i+=1; 
  556.     done
  557. fi
  558.  
  559. # run cal & put its output on coprocess descriptor
  560. cal $month |&
  561.  
  562. # read month & year header from calendar
  563. read -p header
  564. if [[ "$header" = cal:* ]]; then
  565.     echo "Bad month specified."
  566.     exit 1
  567. fi
  568.  
  569. typeset -i width="(hsize+1)*7+1"
  570. # print top bar of calendar
  571. if $short; then
  572.     printhorbar $hsize $tl $t $tr $h | read line
  573.     typeset -i i="(width-${#header})/2"
  574.     while [ i -gt 0 ]; do
  575.     nline=${line#?}
  576.     print -n -- "${line%$nline}"
  577.     line=$nline
  578.     let i-=1
  579.     done
  580.     while [ -n "$header" ]; do
  581.     nline=${header#?}
  582.     print -n -- "${header%$nline}"
  583.     header=$nline
  584.     line=${line#?}
  585.     let i-=1
  586.     done
  587.     print -- "$line"
  588. else
  589.     # set header to be right-justified with size such that it
  590.     # is printed at the middle of the big calendar
  591.     typeset -R$(( (width + ${#header}) / 2 )) header
  592.     echo "$header"
  593.     printhorbar $hsize $tl $t $tr $h
  594. fi
  595.  
  596. # read & discard weekday header
  597. read -p dateline
  598.  
  599. # Print weekday header.  If interior size is less than 9 
  600. # (in which case at least Wednesday would not completely fit),
  601. # abbreviate all days to 3-letter prefix
  602. set -A days Sunday Monday Tuesday Wednesday Thursday Friday Saturday
  603. [ hsize -lt 9 ] && typeset -L3 days
  604. printver $hsize $v 0 ${days[*]}
  605.  
  606. i=0
  607. while read -p dateline; do
  608.     $debug && print -ru2 "Read from date: $dateline"
  609.     # discard blank line printed by cal
  610.     [ -z "$dateline" ] && break
  611.  
  612.     # count numbers in this row.  If less than 7 and this is the first
  613.     # row of numbers, set nulldates to a number of null arguments
  614.     # equal to the difference, so that when dateline is prefixed with
  615.     # them and converted to array the numbers will be in the correct
  616.     # array position rather than elements 0, 1, etc.
  617.     set $dateline
  618.     unset nulldates
  619.     if [ $i = 0 -a $# -lt 7 ]; then
  620.     typeset -L$(( (7 - $#) * 3 )) nulldates
  621.     nulldates='"" "" "" "" "" "" "" '
  622.     fi
  623.     eval set -A dateline $nulldates $dateline
  624.  
  625.     # for each day of the week, use the 0, 1 or 2 digits of the date given
  626.     # by cal to create the digit array for the week in the chosen font.
  627.     # nb[] (the blank digit) is used if there are less than two digits.
  628.     # arrays wdig1n and wdig2n are the first and second digits of the date
  629.     # for weekday n, where n is 0-6 for Sunday-Saturday.
  630.     i=0
  631.     IFS=:
  632.     while [ i -lt 7 ]; do
  633.     dt=${dateline[i]}
  634.     case ${#dt} in
  635.     0) 
  636.         eval set -A wdig1$i '${nb[@]}'
  637.         eval set -A wdig2$i '${nb[@]}';;
  638.     1)
  639.         eval set -A wdig1$i -- '${n'$dt'[@]}'
  640.         eval set -A wdig2$i '${nb[@]}';;
  641.     2)
  642.         eval set -A wdig1$i -- '${n'${dt%?}'[@]}'
  643.         eval set -A wdig2$i -- '${n'${dt#?}'[@]}';;
  644.     esac
  645.     $debug && eval print -ru2 -- \
  646.     \""dt=\$dt  wdig1$i=\${wdig1$i[*]}  wdig2$i=\${wdig2$i[*]}"\"
  647.     let i+=1
  648.     done
  649.  
  650.     # print horizontal bar to separate calendar rectangles
  651.     printhorbar $hsize $l $m $r $h
  652.  
  653.     # for each row of characters that digits are constructed from,
  654.     # print a row of each character separated by $gap.
  655.     # Each pair of char rows and gap becomes a data argument to printver.
  656.     i=0
  657.     while [ i -lt digheight ]; do
  658.     printver $hsize $v $digwidth \
  659.     "${wdig10[i]}$gap${wdig20[i]}" \
  660.     "${wdig11[i]}$gap${wdig21[i]}" \
  661.     "${wdig12[i]}$gap${wdig22[i]}" \
  662.     "${wdig13[i]}$gap${wdig23[i]}" \
  663.     "${wdig14[i]}$gap${wdig24[i]}" \
  664.     "${wdig15[i]}$gap${wdig25[i]}" \
  665.     "${wdig16[i]}$gap${wdig26[i]}"
  666.     let i+=1
  667.     done
  668.  
  669.     # Print field data & finish drawing vertical lines of boxes.
  670.     # o[] has one element for each day of the week.
  671.     # Each element holds the date for that day of the week.
  672.     # The date is used as an index into d[], which holds the field data
  673.     # for each day of the month.
  674.     # For each line to be printed:
  675.     # * The first word of the data for each day of the week is sent to 
  676.     #   printver().  
  677.     # * That word is removed from the data.
  678.     IFS=" "
  679.     set -A o "${dateline[@]}"
  680.     while [ i -lt vsize ]; do
  681.     # eval expands the ${o[n]}'s into real indexes;
  682.     # then ${d[n]%% *} removes all but the first word
  683.     eval printver $hsize '$v' 0 \
  684.     \"${d[${o[0]}]%% *}\" \"${d[${o[1]}]%% *}\" \
  685.     \"${d[${o[2]}]%% *}\" \"${d[${o[3]}]%% *}\" \
  686.     \"${d[${o[4]}]%% *}\" \"${d[${o[5]}]%% *}\" \
  687.     \"${d[${o[6]}]%% *}\"
  688.     # eval expands the ${o[n]}'s into real indexes;
  689.     # then ${d[n]##*([! ])?( )} removes the leftmost word,
  690.     # identified as a string of non-spaces followed by an optional
  691.     # space (optional because the last word may not be followed by
  692.     # a space)
  693.     eval d[${o[0]}]=\"${d[${o[0]}]##*([! ])?( )}\" \
  694.     d[${o[1]}]=\"${d[${o[1]}]##*([! ])?( )}\" \
  695.     d[${o[2]}]=\"${d[${o[2]}]##*([! ])?( )}\" \
  696.     d[${o[3]}]=\"${d[${o[3]}]##*([! ])?( )}\" \
  697.     d[${o[4]}]=\"${d[${o[4]}]##*([! ])?( )}\" \
  698.     d[${o[5]}]=\"${d[${o[5]}]##*([! ])?( )}\" \
  699.     d[${o[6]}]=\"${d[${o[6]}]##*([! ])?( )}\"
  700.     let i+=1
  701.     done
  702. done
  703. # print bottom of calendar
  704. printhorbar $hsize $bl $b $br $h
  705.